package com.ikun.hosuserservice.config;


import com.ikun.common.entity.ResponseResult;
import com.ikun.common.entity.ResponseStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.annotation.Resource;

/**
 * 安全验证配置
 */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UserDetailsService userDetailsService;

    @Resource
    private LoginSuccessHandler loginSuccessHandler;

    /**
     * 提高密码加密对象
     * @return
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * 配置自定义登录逻辑
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //请求授权
        http.authorizeRequests()
                .antMatchers("/login","/register","/code/**","/api/**","/user/**").permitAll() //配置直接放行的请求
                .anyRequest().authenticated()    //其它请求需要登录验证
                .and()
                .formLogin()                    //登录相关配置
                .loginProcessingUrl("/login")   //登录处理的url
                .successHandler(loginSuccessHandler)           //登录成功后的处理
                .failureHandler((httpServletRequest, httpServletResponse, e) -> { //登录失败处理器
                    ResponseResult.write(httpServletResponse,ResponseResult.error(ResponseStatus.LOGIN_ERROR,"登录失败，账号或密码错误"));
                })
                .and()
                .exceptionHandling() //处理未登录的请求
                .authenticationEntryPoint((httpServletRequest, httpServletResponse, e) -> { //登录失败处理器
                    ResponseResult.write(httpServletResponse,ResponseResult.error(ResponseStatus.AUTH_ERROR,"没有权限，请登录"));
                })
                .and()
                .logout() //注销配置
                .logoutUrl("/logout")
                .logoutSuccessHandler((httpServletRequest, httpServletResponse, e) -> { //注销成功处理器
                    ResponseResult.write(httpServletResponse,ResponseResult.ok("注销成功"));
                })
                .clearAuthentication(true)  //清除验证信息
                .and()
                .csrf().disable()           //停止csrf
                .sessionManagement()        //session管理
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS); //无状态，不使用session
    }
}
